/**
 * common utils and modules for develop
 * */
var env = process.env.NODE_ENV || 'development';
var Mapping = require('./config/mapping').Map;
var Config = require('./config/configuration.json')[env];
var log4js = require('log4js');
var mysql = require('mysql');
var tool = require('./mysql-tool');
var crypto = require('crypto');
var mailer = require('nodemailer');

/**
 *  common Const Data Mapping
 * */
exports.Mapping = Mapping;

/**
 *  json configuration
 * */
exports.Config = Config;

/**
 *  application logger
 * */
log4js.configure(Config.log4js);
var logger = log4js.getLogger('app');
exports.logger = logger;

/**
 *  initialize mysql connection pool
 * */
var pool = mysql.createPool(Config.database);
logger.info("MySql Pool Initialized");

var refresh = function () {
    pool.getConnection(function (err, connection) {
        if (err) {
            logger.error(err);
            return;
        }
        connection.query("SELECT u_id AS id, u_name AS `name`,role FROM `user` WHERE `status` = 'active'", function (err, rows) {
            if (err || !rows) {
                logger.error(err);
                return;
            }
            Mapping.userName = {};
            Mapping.userRole = {};
            for (var i in rows) {
                Mapping.userName[rows[i].id] = rows[i].name;
                Mapping.userRole[rows[i].id] = rows[i].role;
            }
            logger.info("User Information Cached");
            connection.release();
        });
    });
};
exports.Pool = pool;
exports.RefreshCache = refresh;

exports.md5 = function (str) {
    var md5sum = crypto.createHash('md5');
    md5sum.update(str);
    str = md5sum.digest('hex');
    return str;
};

/**
 *  Query Implementation, params is optional, to replace $var in query
 * */
var query = function (query, res, params, callback) {
    var cb;
    var queryCopy = query;
    callback ? (cb = callback) : (cb = params);
    if (params) {
        query = tool.sqlParser(query, params);
        if (query.length == 0) {
            logger.error('ORIGIN SQL ERROR : ' + queryCopy);
            return;
        }
    }

    pool.getConnection(function (err, connection) {
        if (err) {
            logger.error(err);
            (process.env.NODE_ENV == 'development') && logger.error(err.stack);
            res && res.send && res.send({error: 501, description: Mapping.error[501]});
            return;
        }

        logger.info('SQL Query Start : ' + query);
        connection.query(query, function (err, rows) {
            if (err) {
                logger.error('SQL Query End : ERROR! ' + err);
                (process.env.NODE_ENV == 'development') && logger.error(err.stack);
                res && res.send && res.send({error: 502, description: Mapping.error[502]});
                return;
            }
            if (params.count && rows instanceof Array) {
                var data = [];
                for (var i = 0; i < rows.length; i++) {
                    if (i >= parseInt(params.limit) && i < parseInt(params.count)) {
                        data.push(rows[i]);
                    }
                }
                cb({data: data, total: rows.length});
            } else {
                cb(rows);
            }
            logger.info('SQL Query End : SUCCESS.');
            //(process.env.NODE_ENV == 'development') && console.log(rows);
            connection.release();
        });
    });
};
exports.Query = query;


/**
 *  Node Mailer API
 * */
exports.Mailer = function(option){
    query("SELECT * FROM config",{},{},function(rows){
        var mailOption = {
            from: rows[0].mail_from,
            to: option.sendTo,
            subject: "新的双周计划已发布!",
            generateTextFromHTML: true,
            html: option.html
        };
        var transport = mailer.createTransport("SMTP", {
            host: "mail.iflytek.com",
            secureConnection: true,
            port: 465,
            auth: {
                user: rows[0].mail_from,
                pass: rows[0].password
            }
        });
        console.log("Mail Content To : " + option.sendTo);
        transport.sendMail(mailOption, function (error, response) {
            if (error) {
                console.log("Monitor Mailer : ERROR " + error);
            } else {
                console.log("Monitor Mailer : Message sent: " + response.message + "\n");
            }
            transport.close();
        });
    });
};

process.on('SIGINT', function () {
    pool.end();
    logger.info("MySql Pool Released");
    process.exit(0);
});

process.on('uncaughtException', function (err) {
    logger.error('Watchman : UncaughtException! ' + err);
    logger.error(err.stack);
});